using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Callbacks;
using UnityEngine;

namespace Super
{
	/// <summary>
	/// 重载脚本管理器
	/// 脚本重新加载后执行管理器methods中的方法
	/// 因为序列化委托是很难的，所以用这样的方法实现重载委托
	/// </summary>
	public class ReloadScriptManager
	{
		private static ReloadScriptManager ins;

		public static ReloadScriptManager Ins
		{
			get
			{
				if (ins == null)
				{
					ins = new ReloadScriptManager();
				}
				return ins;
			}
		}

		public SerializeDict<string, object[]> methods = new SerializeDict<string, object[]>();
		
		/// <summary>
		/// 增加回调方法，方法必须存在MethodCore脚本中
		/// </summary>
		/// <param name="methodName">方法名称</param>
		/// <param name="arguments">参数列表</param>
		/// <param name="isSave">是否保存数据</param>
		public void AddMethod(string methodName, params object[] arguments)
		{
			Ins.methods[methodName] = arguments;
			Ins.methods.SaveData();
			ValueSettingSO.Ins.reloadMethodStr = Ins.methods.dictJson;
			EditorUtility.SetDirty(ValueSettingSO.Ins);  			
		}

		/// <summary>
		/// 重编译脚本后回调的属性
		/// </summary>
		[DidReloadScripts]
		public static void OnDidReloadScripts()
		{
#if !SPINE_PACKAGE
			TryAddDefineSymbol("spine-unity", "SPINE_PACKAGE");
#endif
			TryExecuteMethods();
		}

		/// <summary>
		/// 尝试执行已添加的方法
		/// </summary>
		public static void TryExecuteMethods()
		{
			Ins.methods.dictJson = ValueSettingSO.Ins.reloadMethodStr;
			if (Application.isPlaying || Ins.methods.Count == 0)
			{
				return;
			}

			foreach (var item in Ins.methods.Keys)
			{
				string methodName = item;
				object[] arguments = Ins.methods[item];

				System.Type type = typeof(MethodCore);
				type.GetMethod(methodName)?.Invoke(null, arguments);
			}

			Ins.methods.Clear(true);
			ValueSettingSO.Ins.reloadMethodStr = "";
			EditorUtility.SetDirty(ValueSettingSO.Ins);   	
		}

		/// <summary>
		/// 尝试添加自定义宏，已启动某些框架脚本
		/// </summary>
		/// <param name="assemblyName"></param>
		/// <param name="symbol"></param>
		public static bool TryAddDefineSymbol(string assemblyName, string symbol)
		{
			if (!GlobalUtil.CheckAssemblyExistByName(assemblyName))
				return false;

			BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
			string symbols = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup));
			if (!symbols.Contains(symbol))
			{
				var newSymbols = symbols + ";" + symbol;
				PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup), newSymbols);
				Debug.Log($"向当前平台的ScriptingDefineSymbols添加了{symbol}");
			}
			return true;
		}
	}

}
